<template>
  <view
    class="u-input"
    :class="{
      'u-input--border': border,
      'u-input--error': validateState,
      'u-input--disable': disabled,
    }"
    :style="[
      customStyle,
      {
        padding: padding ? padding : `0 ${border ? 20 : 0}rpx`,
        borderColor: borderColor,
        textAlign: inputAlignCom,
        backgroundColor: backgroundColor,
      },
    ]"
    @tap.stop="inputClick"
  >
    <view class="u-input__input u-input__input-multiple" v-if="valueCom && valueCom.length > 0">
      <u-tag
        v-for="(item, index) in valueCom"
        size="mini"
        :text="item"
        :index="index"
        closeable
        style="margin-right: 0.5em"
        @click="onClick"
        @close="onClose"
    /></view>
    <view class="u-input__input" v-else :style="placeholderStyle"> {{ placeholder }}</view>
    <view class="u-input__right-icon u-flex">
      <view
        class="u-input__right-icon--select u-input__right-icon__item"
        :class="{
          'u-input__right-icon--select--reverse': selectOpen,
        }"
      >
        <u-icon name="arrow-down-fill" size="26" color="#c0c4cc"></u-icon>
      </view>
    </view>
  </view>
</template>

<script>
  import Emitter from '../../libs/util/emitter.js';
  import mpConfig from '../../libs/mixin/mp-vertual-node';

  /**
   * input 输入框
   * @description 此组件为一个输入框，默认没有边框和样式，是专门为配合表单组件u-form而设计的，利用它可以快速实现表单验证，输入内容，下拉选择等功能。
   * @tutorial http://uviewui.com/components/input.html
   * @property {String} type 模式选择，见官网说明
   * @property {Boolean} clearable 是否显示右侧的清除图标(默认true)
   * @property {} v-model 用于双向绑定输入框的值
   * @property {String} input-align 输入框文字的对齐方式(默认left)
   * @property {String} placeholder placeholder显示值(默认 '请输入内容')
   * @property {Boolean} disabled 是否禁用输入框(默认false)
   * @property {String Number} maxlength 输入框的最大可输入长度(默认140)
   * @property {String Number} selection-start 光标起始位置，自动聚焦时有效，需与selection-end搭配使用（默认-1）
   * @property {String Number} maxlength 光标结束位置，自动聚焦时有效，需与selection-start搭配使用（默认-1）
   * @property {String Number} cursor-spacing 指定光标与键盘的距离，单位px(默认0)
   * @property {String} placeholderStyle placeholder的样式，字符串形式，如"color: red;"(默认 "color: #c0c4cc;")
   * @property {String} confirm-type 设置键盘右下角按钮的文字，仅在type为text时生效(默认done)
   * @property {Object} custom-style 自定义输入框的样式，对象形式
   * @property {Boolean} focus 是否自动获得焦点(默认false)
   * @property {Boolean} fixed 如果type为textarea，且在一个"position:fixed"的区域，需要指明为true(默认false)
   * @property {Boolean} password-icon type为password时，是否显示右侧的密码查看图标(默认true)
   * @property {Boolean} border 是否显示边框(默认false)
   * @property {String} border-color 输入框的边框颜色(默认#dcdfe6)
   * @property {Boolean} auto-height 是否自动增高输入区域，type为textarea时有效(默认true)
   * @property {String Number} height 高度，单位rpx(text类型时为70，textarea时为100)
   * @example <u-input v-model="value" :type="type" :border="border" />
   */
  export default {
    name: 'u-input-multiple',
    options: mpConfig,
    emits: ['update:modelValue', 'input', 'change', 'click', 'delete'],
    mixins: [Emitter],
    inject: {
      uFormItem: {
        default() {
          return null;
        },
      },
    },
    props: {
      value: {
        type: [String, Number],
        default: '',
      },
      modelValue: {
        type: [String, Number],
        default: '',
      },
      inputAlign: {
        type: String,
        default: '',
      },
      placeholder: {
        type: String,
        default: '请输入内容',
      },
      disabled: {
        type: Boolean,
        default: false,
      },
      maxlength: {
        type: [Number, String],
        default: 140,
      },
      placeholderStyle: {
        type: String,
        default: 'color: #c0c4cc;',
      },
      confirmType: {
        type: String,
        default: 'done',
      },
      // 输入框的自定义样式
      customStyle: {
        type: Object,
        default() {
          return {};
        },
      },
      // 是否自动获得焦点
      focus: {
        type: Boolean,
        default: false,
      },
      // input|textarea是否显示边框
      border: {
        type: Boolean,
        default: false,
      },
      // 输入框的边框颜色
      borderColor: {
        type: String,
        default: '#dcdfe6',
      },
      autoHeight: {
        type: Boolean,
        default: true,
      },
      // type=select时，旋转右侧的图标，标识当前处于打开还是关闭select的状态
      // open-打开，close-关闭
      selectOpen: {
        type: Boolean,
        default: false,
      },
      // 高度，单位rpx
      height: {
        type: [Number, String],
        default: '',
      },
      // 是否可清空
      clearable: {
        type: [Boolean, String],
      },
      // 指定光标与键盘的距离，单位 px
      cursorSpacing: {
        type: [Number, String],
        default: 0,
      },
      // 是否显示键盘上方带有”完成“按钮那一栏
      showConfirmbar: {
        type: Boolean,
        default: true,
      },
      // input的背景色
      backgroundColor: {
        type: String,
      },
      // input的padding
      padding: {
        type: String,
      },
    },
    data() {
      return {
        defaultValue: '',
        inputHeight: 70, // input的高度
        textareaHeight: 100, // textarea的高度
        validateState: false, // 当前input的验证状态，用于错误时，边框是否改为红色
        focused: false, // 当前是否处于获得焦点的状态
        showPassword: false, // 是否预览密码
        lastValue: '', // 用于头条小程序，判断@input中，前后的值是否发生了变化，因为头条中文下，按下键没有输入内容，也会触发@input时间
        uForm: {
          inputAlign: '',
          clearable: '',
        },
      };
    },
    watch: {
      valueCom(nVal, oVal) {
        this.defaultValue = nVal;
        // 当值发生变化，且为select类型时(此时input被设置为disabled，不会触发@input事件)，模拟触发@input事件
        if (nVal != oVal && this.type == 'select')
          this.handleInput({
            detail: {
              value: nVal,
            },
          });
      },
    },
    computed: {
      valueCom() {
        // #ifndef VUE3
        const value = this.value;
        // #endif

        // #ifdef VUE3
        const value = this.modelValue;
        // #endif

        return Array.isArray(value) ? value : [value];
      },
      inputAlignCom() {
        return this.inputAlign || this.uForm.inputAlign || 'left';
      },
      clearableCom() {
        if (typeof this.clearable == 'boolean') return this.clearable;
        if (typeof this.uForm.clearable == 'boolean') return this.uForm.clearable;
        return true;
      },
      // 因为uniapp的input组件的maxlength组件必须要数值，这里转为数值，给用户可以传入字符串数值
      inputMaxlength() {
        return Number(this.maxlength);
      },
      getStyle() {
        let style = {};
        // 如果没有自定义高度，就根据type为input还是textare来分配一个默认的高度
        style.minHeight = this.height
          ? this.height + 'rpx'
          : this.type == 'textarea'
          ? this.textareaHeight + 'rpx'
          : this.inputHeight + 'rpx';
        style = Object.assign(style);
        return style;
      },
      //
      getCursorSpacing() {
        return Number(this.cursorSpacing);
      },
      // 光标起始位置
      uSelectionStart() {
        return String(this.selectionStart);
      },
      // 光标结束位置
      uSelectionEnd() {
        return String(this.selectionEnd);
      },
    },
    created() {
      // 监听u-form-item发出的错误事件，将输入框边框变红色
      // #ifndef VUE3
      this.$on('onFormItemError', this.onFormItemError);
      // #endif
      this.defaultValue = this.valueCom;
    },
    mounted() {
      if (this.uFormItem) {
        this.uFormItem.triggerInputErrorList?.push(this.onFormItemError.bind(this));
      }
      let parent = this.$u.$parent.call(this, 'u-form');
      if (parent) {
        Object.keys(this.uForm).map((key) => {
          this.uForm[key] = parent[key];
        });
      }
    },
    methods: {
      onClick(index) {
        this.$emit('select', index);
      },
      onClose(index) {
        this.$emit('delete', index);
      },
      onFormItemError(status) {
        this.validateState = status;
      },
      onConfirm(e) {
        this.$emit('confirm', e.detail.value);
      },
      inputClick() {
        // 输入框设置禁用后，不触发点击事件
        if (this.disabled) {
          return;
        }
        this.$emit('click');
      },
    },
  };
</script>

<style lang="scss" scoped>
  @import '../../libs/css/style.components.scss';

  .u-input {
    position: relative;
    flex: 1;
    @include vue-flex;
    align-items: center;

    &__input {
      //height: $u-form-item-height;
      font-size: 28rpx;
      color: $u-main-color;
      flex: 1;
      &-multiple {
        overflow: hidden;
        white-space: nowrap;
        width: 0;
        text-overflow: ellipsis;
      }
    }

    &--border {
      border-radius: 6rpx;
      border-radius: 4px;
      border: 1px solid $u-form-item-border-color;
    }

    &--error {
      border-color: $u-type-error !important;
    }

    &--disable {
      background-color: $u-disable-bg-color;
    }

    &__right-icon {
      &__item {
        margin-left: 10rpx;
      }

      &--select {
        transition: transform 0.4s;

        &--reverse {
          transform: rotate(-180deg);
        }
      }
    }
  }
</style>
